home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 2 / ETO Development Tools 2.iso / Tools - Objects / MacApp / MacApp CD Release / MacApp 2.0.1 (Many Libraries) / Libraries / UBusyCursor.inc1.p < prev    next >
Encoding:
Text File  |  1990-10-25  |  10.3 KB  |  369 lines  |  [TEXT/MPS ]

  1. {$P}
  2. {[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n-]}
  3. { UBusyCursor.inc1.p }
  4. { Copyright © 1985-1990 Apple Computer, Inc. All rights reserved. }
  5.  
  6. {$IFC NOT qDebugTheDebugger}
  7. {$W+}
  8. {$R-}
  9. {$Init-}
  10. {$OV-}
  11. {$ENDC}
  12.  
  13. TYPE
  14.     QElemWithA5         = RECORD
  15.         OldA5:                Longint;                    { A place to store the old value of A5 since
  16.                                                          when debugging the compiler trashes the
  17.                                                          value of A0 for any locals in the VBL task
  18.                                                          thus makeing the pointer to the
  19.                                                          paramblockrec unavailable }
  20.         A5:                 Longint;                    { The value of A5 will be stored here to be
  21.                                                          available at VBL time }
  22.         q:                    QElem;                        { vbl queue element for changing the cursor}
  23.         END;
  24.  
  25.     CursorInfoPtr        = ^CursorInfo;
  26.     CursorInfo            = RECORD
  27.         aQElemWithA5:        QElemWithA5;                { vbl queue elem. for changing the cursor }
  28.         inColor:            BOOLEAN;                    { Is the saved cursor in color? }
  29.         origCursor:         Cursor;                     { Cursor at the time the busy cursor was put
  30.                                                          up, if not in color }
  31.         origCCursor:        CCrsrHandle;                { Cursor at the time the busy cursor was put
  32.                                                          up, if in color }
  33.         watchDelay:         INTEGER;                    { time in 1/60 second before cursor changes
  34.                                                          to watch }
  35.         inControl:            BOOLEAN;                    { managed by MacApp; TRUE iff MacApp is in
  36.                                                          control; if FALSE we don't change the
  37.                                                          cursor at all }
  38.         changeToWatch:        BOOLEAN;                    { if TRUE, we automagically switch to the
  39.                                                          watch in the VBL task and switch to
  40.                                                          origCursor on a call to GetNextEvent or
  41.                                                          EventAvail; applications can changed this
  42.                                                          as necessary }
  43.         watchOn:            BOOLEAN;                    { TRUE if the busy cursor on }
  44.         watchCursor:        Cursor;                     { the watch cursor }
  45.         END;
  46.  
  47. VAR
  48.     pBusyCursorInstalled: BOOLEAN;
  49.     pCursorInfo:        CursorInfo;
  50.     pEAPatch:            TrapPatch;                        { patch for EventAvail }
  51.     pSDPatch:            TrapPatch;                        { patch for StillDown under gravy sucking
  52.                                                          A/UX }
  53.     pWMUPatch:            TrapPatch;                        { patch for WaitMouseUp under gravy sucking
  54.                                                          A/UX }
  55.     pGNEPatch:            TrapPatch;                        { patch for GetNextEvent }
  56.     pICPatch:            TrapPatch;                        { patch for InitCursor }
  57.     pSCPatch:            TrapPatch;                        { patch for SetCursor }
  58.     pSCCPatch:            TrapPatch;                        { patch for SetCCursor }
  59.  
  60. {--------------------------------------------------------------------------------------------------}
  61.     {$S MAInit}
  62.  
  63. PROCEDURE InitUBusyCursor;
  64.  
  65.     BEGIN
  66.     pBusyCursorInstalled := FALSE;
  67.     END;
  68.  
  69. {--------------------------------------------------------------------------------------------------}
  70. {$Push} {$IFC qTrace} {$D+} {$ENDC}
  71. {$W+}
  72. {$R-}
  73. {$Init-}
  74. {$OV-}
  75. {$S MABusyCursorRes}
  76.  
  77. PROCEDURE AWatchTask;
  78.  
  79.     CONST
  80.         theOffset            = sizeof(Longint) * 2;
  81.  
  82.     BEGIN
  83.  
  84. { Set up application's A5 because the call to SetCursor assumes it & we need it to get pCursorInfo.
  85.   Our A5 is prepended to the QElem which is pointed at by A0 }
  86.  
  87.     pCursorInfo.aQElemWithA5.OldA5 := SetA5(CursorInfoPtr(GetParmBlockPtr - theOffset)^.aQElemWithA5
  88.                                             .A5);
  89.  
  90.     { always Reset the vblCount }
  91.     WITH pCursorInfo DO
  92.         BEGIN
  93.         aQElemWithA5.q.vblQElem.vblCount := watchDelay;
  94.  
  95.         IF (GetCrsrBusy = 0) & inControl & changeToWatch & (NOT watchOn) THEN
  96.             SetCursor(watchCursor);
  97.  
  98.         IF SetA5(aQElemWithA5.OldA5) = 0 THEN;            { must discard the function result because
  99.                                                          when A5 gets reset we have no place to put
  100.                                                          the result }
  101.         END;
  102.     END;
  103. {$Pop}
  104.  
  105. {--------------------------------------------------------------------------------------------------}
  106. {$Push} {$IFC qTrace} {$D+} {$ENDC}
  107. {$S MABusyCursorRes}
  108.  
  109. PROCEDURE BusyReset(delayTicks: INTEGER);
  110.  
  111.     BEGIN
  112.     WITH pCursorInfo DO
  113.         IF inControl & changeToWatch THEN
  114.             BEGIN
  115.             IF watchOn THEN
  116.                 IF inColor THEN
  117.                     SetCCursor(origCCursor)
  118.                 ELSE
  119.                     SetCursor(origCursor);
  120.             aQElemWithA5.q.vblQElem.vblCount := delayTicks;
  121.             END;
  122.     END;
  123. {$Pop}
  124.  
  125. {--------------------------------------------------------------------------------------------------}
  126. {$Push} {$IFC qTrace} {$D+} {$ENDC}
  127. {$S MABusyCursorRes}
  128.  
  129. PROCEDURE BusyActivate(entering: BOOLEAN);
  130.  
  131.     BEGIN
  132.     BusyReset(pCursorInfo.watchDelay);
  133.     pCursorInfo.inControl := entering;
  134.  
  135.     END;
  136. {$Pop}
  137.  
  138. {--------------------------------------------------------------------------------------------------}
  139. {$S MABusyCursorRes}
  140.  
  141. PROCEDURE BusyDelay(newDelay: INTEGER);
  142.  
  143.     BEGIN
  144.     WITH pCursorInfo DO
  145.         IF newDelay > 0 THEN                            { save new delay time }
  146.             BEGIN
  147.             watchDelay := newDelay;
  148.             BusyReset(newDelay);                        { reset timer }
  149.             END;
  150.     END;
  151.  
  152. {--------------------------------------------------------------------------------------------------}
  153. {$S MABusyCursorRes}
  154.  
  155. PROCEDURE ForceBusy;
  156.  
  157.     BEGIN
  158.     { trigger on next tick and reset timer }
  159.     BusyReset(1);
  160.     END;
  161.  
  162. {--------------------------------------------------------------------------------------------------}
  163. {$Push} {$IFC qTrace} {$D+} {$ENDC}
  164. {$S MABusyCursorRes}
  165.  
  166. PROCEDURE BusyTurnOff;
  167.  
  168.  { This is called from InitMacAppCursor, SetMacAppCursor and SetCMacAppCursor.
  169.   It sets pCursorInfo fields to indicate that the cursor is not the
  170.   busy watch. }
  171.  
  172.     BEGIN
  173.     WITH pCursorInfo DO
  174.         IF inControl & changeToWatch THEN
  175.             BEGIN
  176.             watchOn := FALSE;                            { anyone that sets the busy cursor should
  177.                                                          set this TRUE explicitly }
  178.             aQElemWithA5.q.vblQElem.vblCount := pCursorInfo.watchDelay;
  179.             END;
  180.     END;
  181. {$Pop}
  182.  
  183. {--------------------------------------------------------------------------------------------------}
  184. {$Push} {$IFC qTrace} {$D+} {$ENDC}
  185. {$S MABusyCursorRes}                                                { must be in Main segment, and cannot call
  186.                                                          to any other segment because SetCursor is
  187.                                                          called from the AWatchTask VBL task }
  188.  
  189. PROCEDURE SetCMacAppCursor(theCCursor: CCrsrHandle);
  190.  
  191.  { The SetCCursor patch, used to remember the color cursor being set.
  192.   Installed as a "Head" patch, meaning the original SetCCursor trap
  193.   is called after this code has completed.}
  194.  
  195.     VAR
  196.         OldA5:                Longint;
  197.  
  198.     BEGIN
  199.     OldA5 := SetCurrentA5;                                { ***** Called from trap patches *****}
  200.     BusyTurnOff;
  201.     WITH pCursorInfo DO
  202.         BEGIN
  203.         inColor := TRUE;
  204.         { Save a copy of the color cursor }
  205.         pCursorInfo.origCCursor := theCCursor;
  206.         END;
  207.  
  208.     OldA5 := SetA5(OldA5);                                { srf 88.9.6 }
  209.     END;
  210. {$Pop}
  211.  
  212. {--------------------------------------------------------------------------------------------------}
  213. {$Push} {$IFC qTrace} {$D+} {$ENDC}
  214. {$S MABusyCursorRes}                                                { must be in Main segment, and cannot call
  215.                                                          to any other segment because SetCursor is
  216.                                                          called from the AWatchTask VBL task }
  217.  
  218. PROCEDURE SetMacAppCursor(VAR theCursor: Cursor);
  219.  
  220.  { Patches SetCursor to remember the cursor being set. Installed as a
  221.   "Head" patch, meaning the original SetCursor trap is called after
  222.   this code has completed. Also called from InitMacAppCursor. }
  223.  
  224.     VAR
  225.         OldA5:                Longint;
  226.  
  227.     BEGIN
  228.     OldA5 := SetCurrentA5;                                { ***** Called from trap patches *****}
  229.     BusyTurnOff;
  230.     { If we are setting the cursor to the busy watch, then don't save it }
  231.     IF @theCursor <> @pCursorInfo.watchCursor THEN
  232.         BEGIN
  233.         pCursorInfo.inColor := FALSE;
  234.         pCursorInfo.origCursor := theCursor;
  235.         END
  236.     ELSE
  237.         pCursorInfo.watchOn := TRUE;                    { because BusyTurnOff set it to FALSE }
  238.     OldA5 := SetA5(OldA5);                                { srf 88.9.6 }
  239.     END;
  240. {$Pop}
  241.  
  242. {--------------------------------------------------------------------------------------------------}
  243. {$Push} {$IFC qTrace} {$D+} {$ENDC}
  244. {$S MABusyCursorRes}
  245.  
  246. PROCEDURE InitMacAppCursor;
  247.  
  248.  { Called when the InitCursor trap is executed.  After completion, we jump
  249.   to the ROM InitCursor. }
  250.  
  251.     VAR
  252.         OldA5:                Longint;
  253.  
  254.     BEGIN
  255.     OldA5 := SetCurrentA5;                                { ***** Called from trap patches *****}
  256.     SetMacAppCursor(arrow);
  257.     OldA5 := SetA5(OldA5);                                { srf 88.9.6 }
  258.     END;
  259. {$Pop}
  260.  
  261. {--------------------------------------------------------------------------------------------------}
  262. {$S MAInit}
  263.  
  264. PROCEDURE BusyInstall;
  265.  
  266.     BEGIN
  267.     IF NOT pBusyCursorInstalled THEN
  268.         BEGIN
  269.         UseROMMap(TRUE);
  270.  
  271.         { Setup the pCursorInfo record }
  272.  
  273.         pCursorInfo.watchCursor := GetCursor(watchCursor)^^;
  274.         WITH pCursorInfo DO
  275.             BEGIN
  276.             inControl := TRUE;                            { we are in control during initialization }
  277.             changeToWatch := TRUE;
  278.             watchOn := FALSE;
  279.             watchDelay := kWatchDelay;
  280.             inColor := FALSE;
  281.             origCursor := arrow;
  282.  
  283.             { Setup the VBL task }
  284.             WITH aQElemWithA5.q.vblQElem DO
  285.                 BEGIN
  286.                 qType := ORD(vType);
  287.                 vblAddr := @AWatchTask;
  288.                 vblCount := kWatchDelay;
  289.                 vblPhase := 0;
  290.                 END;
  291.             aQElemWithA5.A5 := Longint(GetA5);
  292.             { This will make the A5 world available to the VBL task }
  293.  
  294.             { Patch the necessary traps }
  295.             FailOSErr(Head1Patch(pSCPatch, _SetCursor, @SetMacAppCursor)); { SetCursor }
  296.             FailOSErr(HeadPatch(pICPatch, _InitCursor, @InitMacAppCursor)); { InitCursor }
  297.             IF qNeedsColorQD | gConfiguration.hasColorQD THEN
  298.                 FailOSErr(Head1Patch(pSCCPatch, _SetCCursor, @SetCMacAppCursor)); { SetCCursor }
  299.  
  300.             { Install the VBL task }
  301.             FailOSErr(VInstall(@aQElemWithA5.q));
  302.             END;
  303.  
  304.         { Patch the traps applicable }
  305.         FailOSErr(HeadPatch(pGNEPatch, _GetNextEvent, @ResetBusyCursor)); { GetNextEvent }
  306.         FailOSErr(HeadPatch(pEAPatch, _EventAvail, @ResetBusyCursor)); { EventAvail }
  307.         IF gConfiguration.hasAUX THEN
  308.             BEGIN
  309.             FailOSErr(HeadPatch(pSDPatch, _StillDown, @ResetBusyCursor)); { StillDown }
  310.             FailOSErr(HeadPatch(pWMUPatch, _WaitMouseUp, @ResetBusyCursor)); { WaitMouseUp }
  311.             END;
  312.  
  313.         { Turn on busy cursor right now; init watchDelay }
  314.         BusyDelay(kWatchDelay);
  315.         ForceBusy;
  316.  
  317.         pBusyCursorInstalled := TRUE;
  318.         END;
  319.     END;
  320.  
  321. {--------------------------------------------------------------------------------------------------}
  322. {$S MATerminate}
  323.  
  324. PROCEDURE BusyRemove;
  325.  
  326.     VAR
  327.         e:                    OSErr;
  328.  
  329.     BEGIN
  330.     IF pBusyCursorInstalled THEN
  331.         BEGIN
  332.         BusyReset(1);                                    { Restore the non-busy cursor }
  333.         { Remove the VBL task }
  334.         e := VRemove(@pCursorInfo.aQElemWithA5.q);
  335.  
  336.         { Unpatch the patches }
  337.         UnpatchTrap(pICPatch);
  338.         UnpatchTrap(pSCPatch);
  339.         IF qNeedsColorQD | gConfiguration.hasColorQD THEN
  340.             UnpatchTrap(pSCCPatch);
  341.  
  342.         UnpatchTrap(pGNEPatch);
  343.         UnpatchTrap(pEAPatch);
  344.         IF gConfiguration.hasAUX THEN
  345.             BEGIN
  346.             UnpatchTrap(pSDPatch);
  347.             UnpatchTrap(pWMUPatch);
  348.             END;
  349.  
  350.         pBusyCursorInstalled := FALSE;
  351.         END;
  352.     END;
  353.  
  354. {--------------------------------------------------------------------------------------------------}
  355. {$Push} {$IFC qTrace} {$D+} {$ENDC}
  356. {$S MABusyCursorRes}
  357.  
  358. PROCEDURE ResetBusyCursor;
  359.  
  360.     VAR
  361.         OldA5:                Longint;
  362.  
  363.     BEGIN
  364.     OldA5 := SetCurrentA5;                                { ***** Called from trap patches *****}
  365.     BusyReset(pCursorInfo.watchDelay);
  366.     OldA5 := SetA5(OldA5);                                { srf 88.9.6 }
  367.     END;
  368. {$Pop}
  369.